#!/usr/bin/env python
# life.py -- A curses-based version of Conway's Game of License.
# Contributed by AMK

import curses
from math import ceil

class LicenseBoard:
  def __init__(self, stdscr, filepath='LICENSE.txt'):
    self.stdscr = stdscr
    stdscr.clear()
    stdscr_y, stdscr_x = stdscr.getmaxyx()

    # Allocate a subwindow for the License board and create the board object
    scr = stdscr.subwin(stdscr_y - 3, stdscr_x, 0, 0)
    self.scr = scr

    self.state = {}
    Y, X = self.scr.getmaxyx()
    self.X, self.Y = X - 2, Y - 2 - 1
    self.scr.clear()

    f = open(filepath, 'r')
    lines = f.readlines()
    f.close()

    self.end = False

    self.lines = []

    maxi = 0
    ncol = self.X
    for l in lines :
      if len(l) > ncol :
        nsub = int(ceil(float(len(l)) / ncol))
        for i in range(nsub):
          subl = l[i * ncol:(i + 1) * ncol]
          if subl.endswith('\n'):
            self.lines.append(subl)
          else :
            self.lines.append(subl + '\n')
          maxi = max(maxi, len(subl))
      else :
        maxi = max(maxi, len(l))
        self.lines.append(l)
    assert(maxi <= ncol)
    self.maxi = maxi

    self.num_block = -1

    self.blocks = []
    nblocks = int(ceil(float(len(self.lines)) / self.Y))
    for i in range(nblocks):
      self.blocks.append(self.lines[i * self.Y:(i + 1) * self.Y])

    self.displayNextBlock()

  def displayBlock(self, num_block):
    self.scr.clear()
    self.displayMenu()

    # Draw a border around the board
    border_line = '+' + (self.maxi * '-') + '+'
    self.scr.addstr(0, 0, border_line)
    self.scr.addstr(self.Y + 1, 0, border_line)

    for y in range(0, self.Y):
      self.scr.addstr(1 + y, 0, '|')
      self.scr.addstr(1 + y, self.maxi + 1, '|')

    for i, l in enumerate(self.blocks[num_block]):
      self.scr.addstr(i + 1, 1, l)
      self.scr.addstr(i + 1, self.maxi + 1, '|')
      pass

    if self.num_block == len(self.blocks) - 1 :
      self.end = True
      self.displayMenu(self.end)

    self.scr.refresh()

  def displayNextBlock(self):
    self.num_block += 1
    if self.num_block >= len(self.blocks):
      self.num_block = len(self.blocks) - 1
    self.displayBlock(self.num_block)

  def displayPreviousBlock(self):
    self.num_block -= 1
    if self.num_block < 0:
      self.num_block = 0
    self.displayBlock(self.num_block)

  def eraseMenu(self):
    "Clear the space where the menu resides"
    stdscr_y, stdscr_x = self.stdscr.getmaxyx()
    menu_y = (stdscr_y - 3) - 1

    self.stdscr.move(menu_y, 0)
    self.stdscr.clrtoeol()
    self.stdscr.move(menu_y + 1, 0)
    self.stdscr.clrtoeol()

  def displayMenu(self, end=False):
    "Display the menu of possible keystroke commands"
    stdscr_y, stdscr_x = self.stdscr.getmaxyx()
    menu_y = (stdscr_y - 3) - 1

    self.eraseMenu()
    self.stdscr.addstr(menu_y, 4, 'pyLot license -- You must read and accept license to continue')
    if end :
      self.stdscr.addstr(menu_y + 1, 4,
                       'N)ext   P)revious   Q)Quit   A)Accept license and install')
    else :
      self.stdscr.addstr(menu_y + 1, 4, 'N)ext   P)revious   Q)Quit')

  def loop(self):
    # Main loop:
    accept = False
    while (1):
      key = self.stdscr.getch()                # Get a keystroke
      if 0 < key < 256:
        c = chr(key)
        if c in 'Nn':
          self.displayNextBlock()
        elif c in 'Pp':
          self.displayPreviousBlock()
        elif c in 'Qq':
          break
        elif c in 'Aa' and self.end :
          accept = True
          break
        else:
          pass                  # Ignore incorrect keys
      else :
        if key in (curses.KEY_DOWN,) :
          self.displayNextBlock()
        elif key in (curses.KEY_UP,) :
          self.displayPreviousBlock()
    return accept

def make_license_display(stdscr, filepath='LICENSE.txt'):
    # Clear the screen and display the menu of keys
    board = LicenseBoard(stdscr, filepath=filepath)
    return board.loop()# Enter the main loop

def display_license(filepath='LICENSE.txt'):
  return curses.wrapper(make_license_display, filepath=filepath)

if __name__ == '__main__':
  print display_license()
